/********************************************************************************
* @file    multiplexer_8ch_core.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2022-02-09
* @brief   multiplexer简称mux
           1. 通过A0-A2电平,控制X0-7中哪个脚接入公共脚Z0
           2. A0-A2电平组成0-7，对应X0-7。
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

/* Private Includes ----------------------------------------------------------*/
#include "multiplexer_8ch_core.h"
#include "hc4051.h"
#include "log.h"
#include "ls_gpio.h"
#include "ls_syscfg.h"
/* Private Define ------------------------------------------------------------*/
/* Private Typedef -----------------------------------------------------------*/
/* Private Macro -------------------------------------------------------------*/
/* Private Variables ---------------------------------------------------------*/
#if LS_MULTIPLEXER_8CH_SWITCH
static const mux_gpio_t g_gpio_init[LS_MULTIPLEXER_8CH_NUM] =
{
#if (LS_MULTIPLEXER_8CH_NUM > 0)
    {
        .en_pin = {LS_MUX0_EN_GPIO_PORT, LS_MUX0_EN_PIN, LS_MUX0_EN_GPIO_CLK, LS_MUX0_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a0_pin = {LS_MUX0_A0_GPIO_PORT, LS_MUX0_A0_PIN, LS_MUX0_EN_GPIO_CLK, LS_MUX0_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a1_pin = {LS_MUX0_A1_GPIO_PORT, LS_MUX0_A1_PIN, LS_MUX0_EN_GPIO_CLK, LS_MUX0_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a2_pin = {LS_MUX0_A2_GPIO_PORT, LS_MUX0_A2_PIN, LS_MUX0_EN_GPIO_CLK, LS_MUX0_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
    },
#endif
#if (LS_MULTIPLEXER_8CH_NUM > 1)
    {
        .en_pin = {LS_MUX1_EN_GPIO_PORT, LS_MUX1_EN_PIN, LS_MUX1_EN_GPIO_CLK, LS_MUX1_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a0_pin = {LS_MUX1_A0_GPIO_PORT, LS_MUX1_A0_PIN, LS_MUX1_EN_GPIO_CLK, LS_MUX1_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a1_pin = {LS_MUX1_A1_GPIO_PORT, LS_MUX1_A1_PIN, LS_MUX1_EN_GPIO_CLK, LS_MUX1_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a2_pin = {LS_MUX1_A2_GPIO_PORT, LS_MUX1_A2_PIN, LS_MUX1_EN_GPIO_CLK, LS_MUX1_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
    },
#endif
#if (LS_MULTIPLEXER_8CH_NUM > 2)
    {
        .en_pin = {LS_MUX2_EN_GPIO_PORT, LS_MUX2_EN_PIN, LS_MUX2_EN_GPIO_CLK, LS_MUX2_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a0_pin = {LS_MUX2_A0_GPIO_PORT, LS_MUX2_A0_PIN, LS_MUX2_EN_GPIO_CLK, LS_MUX2_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a1_pin = {LS_MUX2_A1_GPIO_PORT, LS_MUX2_A1_PIN, LS_MUX2_EN_GPIO_CLK, LS_MUX2_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a2_pin = {LS_MUX2_A2_GPIO_PORT, LS_MUX2_A2_PIN, LS_MUX2_EN_GPIO_CLK, LS_MUX2_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
    },
#endif
#if (LS_MULTIPLEXER_8CH_NUM > 3)
    {
        .en_pin = {LS_MUX3_EN_GPIO_PORT, LS_MUX3_EN_PIN, LS_MUX3_EN_GPIO_CLK, LS_MUX3_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a0_pin = {LS_MUX3_A0_GPIO_PORT, LS_MUX3_A0_PIN, LS_MUX3_EN_GPIO_CLK, LS_MUX3_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a1_pin = {LS_MUX3_A1_GPIO_PORT, LS_MUX3_A1_PIN, LS_MUX3_EN_GPIO_CLK, LS_MUX3_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a2_pin = {LS_MUX3_A2_GPIO_PORT, LS_MUX3_A2_PIN, LS_MUX3_EN_GPIO_CLK, LS_MUX3_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
    },
#endif
#if (LS_MULTIPLEXER_8CH_NUM > 4)
    {
        .en_pin = {LS_MUX4_EN_GPIO_PORT, LS_MUX4_EN_PIN, LS_MUX4_EN_GPIO_CLK, LS_MUX4_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a0_pin = {LS_MUX4_A0_GPIO_PORT, LS_MUX4_A0_PIN, LS_MUX4_EN_GPIO_CLK, LS_MUX4_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a1_pin = {LS_MUX4_A1_GPIO_PORT, LS_MUX4_A1_PIN, LS_MUX4_EN_GPIO_CLK, LS_MUX4_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a2_pin = {LS_MUX4_A2_GPIO_PORT, LS_MUX4_A2_PIN, LS_MUX4_EN_GPIO_CLK, LS_MUX4_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
    },
#endif
#if (LS_MULTIPLEXER_8CH_NUM > 5)
    {
        .en_pin = {LS_MUX5_EN_GPIO_PORT, LS_MUX5_EN_PIN, LS_MUX5_EN_GPIO_CLK, LS_MUX5_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a0_pin = {LS_MUX5_A0_GPIO_PORT, LS_MUX5_A0_PIN, LS_MUX5_EN_GPIO_CLK, LS_MUX5_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a1_pin = {LS_MUX5_A1_GPIO_PORT, LS_MUX5_A1_PIN, LS_MUX5_EN_GPIO_CLK, LS_MUX5_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a2_pin = {LS_MUX5_A2_GPIO_PORT, LS_MUX5_A2_PIN, LS_MUX5_EN_GPIO_CLK, LS_MUX5_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
    },
#endif
#if (LS_MULTIPLEXER_8CH_NUM > 6)
    {
        .en_pin = {LS_MUX6_EN_GPIO_PORT, LS_MUX6_EN_PIN, LS_MUX6_EN_GPIO_CLK, LS_MUX6_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a0_pin = {LS_MUX6_A0_GPIO_PORT, LS_MUX6_A0_PIN, LS_MUX6_EN_GPIO_CLK, LS_MUX6_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a1_pin = {LS_MUX6_A1_GPIO_PORT, LS_MUX6_A1_PIN, LS_MUX6_EN_GPIO_CLK, LS_MUX6_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a2_pin = {LS_MUX6_A2_GPIO_PORT, LS_MUX6_A2_PIN, LS_MUX6_EN_GPIO_CLK, LS_MUX6_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
    },
#endif
#if (LS_MULTIPLEXER_8CH_NUM > 7)
    {
        .en_pin = {LS_MUX7_EN_GPIO_PORT, LS_MUX7_EN_PIN, LS_MUX7_EN_GPIO_CLK, LS_MUX7_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a0_pin = {LS_MUX7_A0_GPIO_PORT, LS_MUX7_A0_PIN, LS_MUX7_EN_GPIO_CLK, LS_MUX7_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a1_pin = {LS_MUX7_A1_GPIO_PORT, LS_MUX7_A1_PIN, LS_MUX7_EN_GPIO_CLK, LS_MUX7_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
        .a2_pin = {LS_MUX7_A2_GPIO_PORT, LS_MUX7_A2_PIN, LS_MUX7_EN_GPIO_CLK, LS_MUX7_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
    },
#endif
};
#endif
/* Private Function Prototypes -----------------------------------------------*/
/* Public Function Prototypes ------------------------------------------------*/
/**
 * @brief  8路分流器初始化 使能引脚时钟 配置为推免输出
 */
void mux_init(void)
{
    uint8_t i;

    for (i = 0; i < LS_MULTIPLEXER_8CH_NUM; i++)
    {
        /* Enable the GPIO Clock */
        bsp_gpio_set_clk(GPIO_APBx, g_gpio_init[i].en_pin.periph, true);
        /* Configure the GPIO pin */
        bsp_gpio_init_output(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin, BSP_GPIO_PIN_OUT_PP);
        /* Reset PIN to switch off the */
        bsp_gpio_set_pin(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].en_pin.level);

        /* Enable the GPIO Clock */
        bsp_gpio_set_clk(GPIO_APBx, g_gpio_init[i].a0_pin.periph, true);
        /* Configure the GPIO pin */
        bsp_gpio_init_output(g_gpio_init[i].a0_pin.port, g_gpio_init[i].a0_pin.pin, BSP_GPIO_PIN_OUT_PP);
        /* Reset PIN to switch off the */
        bsp_gpio_set_pin(g_gpio_init[i].a0_pin.port, g_gpio_init[i].a0_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a0_pin.level);

        /* Enable the GPIO Clock */
        bsp_gpio_set_clk(GPIO_APBx, g_gpio_init[i].a1_pin.periph, true);
        /* Configure the GPIO pin */
        bsp_gpio_init_output(g_gpio_init[i].a1_pin.port, g_gpio_init[i].a1_pin.pin, BSP_GPIO_PIN_OUT_PP);
        /* Reset PIN to switch off the */
        bsp_gpio_set_pin(g_gpio_init[i].a1_pin.port, g_gpio_init[i].a1_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a1_pin.level);

        /* Enable the GPIO Clock */
        bsp_gpio_set_clk(GPIO_APBx, g_gpio_init[i].a2_pin.periph, true);
        /* Configure the GPIO pin */
        bsp_gpio_init_output(g_gpio_init[i].a2_pin.port, g_gpio_init[i].a2_pin.pin, BSP_GPIO_PIN_OUT_PP);
        /* Reset PIN to switch off the */
        bsp_gpio_set_pin(g_gpio_init[i].a2_pin.port, g_gpio_init[i].a2_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a2_pin.level);
    }
}

/**
 * @brief  8路分流器反初始化 将引脚配置为浮空输入
 */
void mux_deinit(void)
{
    uint8_t i;

    if (LS_MULTIPLEXER_8CH_NUM == 0)
    {
        return;
    }

    for (i = 0; i < LS_MULTIPLEXER_8CH_NUM; i++)
    {
        /* Turn off */
        bsp_gpio_set_pin(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].en_pin.level);
        /* DeInit the GPIO pin */
        bsp_gpio_deinit(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin);

        /* Turn off */
        bsp_gpio_set_pin(g_gpio_init[i].a0_pin.port, g_gpio_init[i].a0_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a0_pin.level);
        /* DeInit the GPIO pin */
        bsp_gpio_deinit(g_gpio_init[i].a0_pin.port, g_gpio_init[i].a0_pin.pin);

        /* Turn off */
        bsp_gpio_set_pin(g_gpio_init[i].a1_pin.port, g_gpio_init[i].a1_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a1_pin.level);
        /* DeInit the GPIO pin */
        bsp_gpio_deinit(g_gpio_init[i].a1_pin.port, g_gpio_init[i].a1_pin.pin);

        /* Turn off */
        bsp_gpio_set_pin(g_gpio_init[i].a2_pin.port, g_gpio_init[i].a2_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a2_pin.level);
        /* DeInit the GPIO pin */
        bsp_gpio_deinit(g_gpio_init[i].a2_pin.port, g_gpio_init[i].a2_pin.pin);
    }
}

/**
 * @brief  设置指定通道至公共点
 * @param  id: 器件号
 * @param  ch: 设置ch到公共点
 */
void mux_set_ch(uint8_t id, uint8_t ch)
{
    /* 关闭使能 */
    bsp_gpio_set_pin(g_gpio_init[id].en_pin.port, g_gpio_init[id].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[id].en_pin.level);
    /* 绑定指定通道至公共点 */
    bsp_gpio_set_pin(g_gpio_init[id].a0_pin.port, g_gpio_init[id].a0_pin.pin, ch & 0x01);
    bsp_gpio_set_pin(g_gpio_init[id].a1_pin.port, g_gpio_init[id].a1_pin.pin, (ch >> 1) & 0x01);
    bsp_gpio_set_pin(g_gpio_init[id].a2_pin.port, g_gpio_init[id].a2_pin.pin, (ch >> 2) & 0x01);
    /* 打开使能 */
    bsp_gpio_set_pin(g_gpio_init[id].en_pin.port, g_gpio_init[id].en_pin.pin, (bsp_gpio_pin_state_t)g_gpio_init[id].en_pin.level);
}

/**
 * @brief  关闭所有器件
 */
void mux_close_all_ic(void)
{
    uint8_t i;

    for (i = 0; i < LS_MULTIPLEXER_8CH_NUM; i++)
    {
        bsp_gpio_set_pin(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].en_pin.level);
    }
}

/**
 * @brief  关闭指定器件
 */
void mux_close_ic(uint8_t id)
{
    bsp_gpio_set_pin(g_gpio_init[id].en_pin.port, g_gpio_init[id].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[id].en_pin.level);
}
